#include "gx_util.h"
int getaddrlist(char* host,char* serve,struct addrinfo** res)
{
	struct addrinfo hints;
	hints.ai_flags = AI_CANONNAME;
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = 0;
	hints.ai_addrlen = 0;
	hints.ai_addr = NULL;
	hints.ai_canonname = NULL;
	hints.ai_next = NULL;
	return getaddrinfo(host,serve,&hints,res);
}

size_t tread(int fd,void* buf,size_t bufsize,int timeout)
{
	fd_set readfd;
	FD_ZERO(&readfd);
	FD_SET(fd,&readfd);
	struct timeval outtime;
	outtime.tv_sec = timeout;
	outtime.tv_usec = 0;

	int ready = select(fd+1,&readfd,NULL,NULL,&outtime);

	if(ready == 0)
	{
		errno = ETIME;
		return 0;
	}
	else if(ready < 0)
	{
		return 0;
	}
	else
	{
		return read(fd,buf,bufsize);
	}
}

size_t treadn(int fd,char* buf,size_t readsize,int timeout)
{
	size_t readn;
	size_t leftn;
	leftn = readsize;

	while(leftn > 0)
	{
		if((readn = tread(fd,buf,readsize,timeout)) <= 0)
		{
			if(leftn == readsize)
				return -1;
			else 
				break;
		}

		leftn -= readn;
		buf+= readn;
	}

	return readsize-leftn;
}

ssize_t readn(int fd, char *ptr,size_t n)
{
	size_t nleft;
	size_t nread;
	nleft = n;

	while(nleft > 0)
	{
		if((nread = read(fd,ptr,nleft)) < 0)
		{
			if(nleft == n)
				return -1;
			else
				break;
		}
		else if(nread == 0)
		{
			break;
		}
		nleft -= nread;
		ptr += nread;
	}
	return (n - nleft);
}

ssize_t writen(int fd,const char *ptr,size_t n)
{
	size_t nleft;
	size_t nwritten;
	nleft = n;
	while(nleft>0)
	{
		if((nwritten= write(fd,ptr,nleft)) < 0)
		{
			if(nleft == n)
				return -1;
			else
				break;
		}
		else if(nwritten == 0)
		{
			break;
		}
		nleft -= nwritten;
		ptr += nwritten;
	}
	return (n - nleft);
}

typedef void (*my_handler)(int);

my_handler my_signal(int signo,my_handler func)
{
	struct sigaction act,oact;
	act.sa_handler = func;
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;

	if(signo == SIGALRM)
	{
#ifdef SA_INTERRUPT
		act.sa_flags |= SA_INTERRUPT;
#endif
	}
	else
	{
#ifdef SA_RESTART
		act.sa_flags |= SA_RESTART;
#endif
	}
	if(sigaction(signo,&act,&oact) < 0)
		return SIG_ERR;
	//return oact.sa_handler;
	return 0;
}
